var labelType, useGradients, nativeTextSupport, animate;

(function() {
  var ua = navigator.userAgent,
      iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
      typeOfCanvas = typeof HTMLCanvasElement,
      nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
      textSupport = nativeCanvasSupport 
        && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
  //I'm setting this based on the fact that ExCanvas provides text support for IE
  //and that as of today iPhone/iPad current text support is lame
  labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
  nativeTextSupport = labelType == 'Native';
  useGradients = nativeCanvasSupport;
  animate = !(iStuff || !nativeCanvasSupport);
})();

var colors = [ "#4E9258", "#348781", "#617C58", "#307D7E", "#3B9C9C",    ]; 

function make_tag_links() {
		if ($('#infovis-label').children().length == 0) {
			return false;
		}
		var nodeIds = [];
		$('#infovis-label').children().each(function(index) {
			if ($(this).css('display') != 'none') {
				nodeIds.push($(this).attr('id'));
			}
		});
		nodeIds.sort();
		var html = '<table><tbody><tr>';
		for (var i in nodeIds) {
			if (i % 4 == 0) {
				html += '</tr><tr>';
			}
			html += '<td><a href="/msc/' + nodeIds[i] + '">' + nodeIds[i] + '</a></td>';
		}
		$jit.id('inner-details').innerHTML = html + '</tr><tbody></table>';
};
	//correct JIT's labling order, which first goes from up to down, left to right until row=column, then the upper left to the lower left, then from upper left to upper right, then from upper left to lower right
function correct_ordering(arr, rowNum, colNum) {
	var buckets = [];
	// get correct order
	var count = 0;
	for (var i = 0; i < rowNum; i++) {
		buckets[i] = []
		for (var j=0; j < colNum; j++){
			buckets[i][j] = [count];
			count++;
		}
	}
	// get incorrect order
	count = 0;
	for (var j = 0; j < (colNum - rowNum); j++) {
		for (var i=0; i < rowNum; i++) {
			buckets[i][j].push(count);
			count++;
		}
	}
	for (var i = 0; i < rowNum; i++) {
		for (var j = i; j < rowNum; j++){
			var col = i + (colNum - rowNum);
			buckets[j][col].push(count);
			count++;
		}
		for (var k = i+1+(colNum - rowNum); k < colNum; k++) {
			buckets[i][k].push(count);
			count++;
		}
	}
	var new_arr = [];
	for (var i=0; i < rowNum; i++) {
		for (var j=0; j<colNum; j++) {
			new_arr[buckets[i][j][1]] = arr[buckets[i][j][0]];
		}
	}
	return new_arr;
};



$(function(){
  //init TreeMap
  var tm = new $jit.TM.Squarified({
     injectInto: 'infovis', //where to inject the visualization
     levelsToShow: 1, //show only one tree level
     titleHeight: 0, //parent box title heights
     animate: animate, //enable animations
     offset: 1, //box offsets
     //use canvas text
     Label: {
       type: 'HTML', // type: labelType,
       size: 10,
       family: 'Tahoma, Verdana, Arial',
     },
     //enable specific canvas styles when rendering nodes
     Node: {
       CanvasStyles: {
         shadowBlur: 0,
         shadowColor: '#000'
       }
     },
     //Attach left and right click events
     Events: {
       enable: true,
       onClick: function(node) {
         if(node) tm.enter(node);
       },
       onRightClick: function() {
         tm.out();
       },
       //change node styles and canvas styles
       //when hovering a node
       onMouseEnter: function(node, eventInfo) {
         if(node) {
           //add node selected styles and replot node
           node.setCanvasStyle('shadowBlur', 7);
           // node.setData('color', '#888');
           tm.fx.plotNode(node, tm.canvas);
           // tm.labels.plotLabel(tm.canvas, node);
           tm.labels.plotLabel(tm.canvas, node, tm.controller);
         }
       },
       onMouseLeave: function(node) {
         if(node) {
           // node.removeData('color');
           node.removeCanvasStyle('shadowBlur');
           tm.plot();
         }
       }
     },
     //duration of the animations
     duration: 200,
     //Enable tips
     Tips: {
       enable: true,
       type: 'Native',
       //add positioning offsets
       offsetX: 20,
       offsetY: 20,
       //implement the onShow method to add content to the tooltip when a node is hovered
       onShow: function(tip, node, isLeaf, domElement) {
         var html = '<div class=\"tip-title\">' + node.id 
           + '</div><div class=\"tip-text\" align="left">';
		html += '<ul>';
		for (var i in node.data.defns){
			html += '<li>' + node.data.defns[i].defnText + '</li>';
		}
		html += '</ul>' + "</div>"
        // tip.innerHTML =  html; 
		// dispaly tip text in inner-details instead
		$jit.id('inner-details').innerHTML = html;
       }  
     },
     //Implement this method for retrieving a requested  
     //subtree that has as root a node with id = nodeId,  
     //and level as depth. This method could also make a server-side  
     //call for the requested subtree. When completed, the onComplete   
     //callback method should be called.  
     request: function(nodeId, level, onComplete){  
		var startkey = [nodeId.substring(0,2)];
		var endkey = [nodeId.substring(0,2), {}];
		var url = '/couchdb/msc2010/_design/msc/_view/by_tag?include_docs=true&startkey=' + JSON.stringify(startkey) + '&endkey=' + JSON.stringify(endkey) ;
	    $.getJSON(url, function(data) {
			json = {"id": nodeId,
					"name": nodeId,
					"data": {},
					"children": []};
			// get node's doc
			var node_doc;
			for (var i in data.rows) {
				if (data.rows[i].id == nodeId) {
					node_doc = data.rows[i].doc;
				}
			}	
			// get children's doc
			var child_level=-1, children_rows=[];
			if (nodeId.substring(3,5) == '++') {
				child_level = 1;
				for (var i in data.rows) {
					if (data.rows[i].value == child_level) {
						children_rows.push(data.rows[i]);
					}
				}
			}
			if (nodeId.substring(3,5) == 'xx') {
				child_level = 2;
				for (var i in data.rows) {
					if ((data.rows[i].value == child_level) && (data.rows[i].doc.tag[1] == nodeId.substring(2,3))) {
						children_rows.push(data.rows[i]);
					}
				}
			}
			node_doc['$area'] = 271;
			node_doc['$color'] = colors[parseInt((Math.random()-0.001)*colors.length)];
			json.data = node_doc;
			for (var i in children_rows) {
				children_rows[i].doc['$area'] = 271;
				children_rows[i].doc['$color'] = colors[parseInt((Math.random()-0.001)*colors.length)];
				json.children.push({"id": children_rows[i].id,
									"name": children_rows[i].id,
									"data": children_rows[i].doc,
									"children": []});
			}
			onComplete.onComplete(nodeId, json);
			// // make tag links
			// var nodeIds = [];
			// for (var i in json.children) {
			// 	nodeIds.push(json.children[i].id);
			// }
			// nodeIds.sort();
			// make_tag_links(nodeIds);
		});
     },
     //Add the name of the node in the corresponding label
     //This method is called once, on label creation and only for DOM labels.
     onCreateLabel: function(domElement, node){
		var max_char = 35;
		if (node.data.level > 0) {
			max_char = 500;
		}
		// shorten defn text
		var defn_text = "";
		for (var i in node.data.defns) {
			defn_text += node.data.defns[i].defnText + '<br/>';
		}
		if (defn_text.length > max_char) {
			defn_text = defn_text.substring(0,50) + '<br />...';
		}
        domElement.innerHTML = '<div style="padding: 2px"><a href="/msc/' + node.name + '">' + node.name + "</a><br/>" + defn_text + "</div>";
     },
	onAfterCompute: function() {
		$('#log').html('');
		// make_tag_links();
	},
   });
   
 
	
  //init data
	var json;
	var url = '/couchdb/msc2010/_design/msc/_view/by_level?include_docs=true&key=0';
	$.getJSON(url, function(data) {	
		// data.rows.sort(function (a,b) {var x=a.id, y=b.id; return ((x < y) ? -1 : (x == y) ? 0 : 1);});
		data.rows = correct_ordering(data.rows, 7, 9);	
		json = {"id": "msc2010",
				"name": "MSC 2010",
				"data": {},
				"children": []};
		for (var i in data.rows) {
			doc = data.rows[i].doc;
			doc['$area'] = 100;
			doc['$color'] = colors[parseInt((Math.random()-0.001)*colors.length)];
			json.children.push({"id": data.rows[i].id,
								"name": data.rows[i].id,
								"data": doc,
								"children": []});
		}
		init_infovis(json);	
		// make tag links
		var nodeIds = [];
		for (var i in json.children) {
			nodeIds.push(json.children[i].id);
		}
		nodeIds.sort();		
	});
 	//end

   function init_infovis(json) {
	   tm.loadJSON(json);
	   tm.refresh();
	};
   //end
   //add event to the back button
   var back = $jit.id('back');
   $jit.util.addEvent(back, 'click', function() {
     tm.out();
   }); 
});
